package main

import (
	"machine"
	"time"
)

const (
	OLED_CMD  = 0
	OLED_DATA = 1
)

var (
	PA5 = machine.A5 //sck
	PA7 = machine.A7 //dio
	PA4 = machine.A4 //dc
	PA3 = machine.A3 //res
	PA2 = machine.A2 //cs

)

var (
	OLED_GRAM [144][8]byte
)

func OLED_SCL_Clr() {
	PA5.Low()
}

func OLED_SCL_Set() {
	PA5.High()
}

func OLED_SDA_Clr() {
	PA7.Low()
}

func OLED_SDA_Set() {
	PA7.High()
}

func OLED_DC_Clr() {
	PA4.Low()
}

func OLED_DC_Set() {
	PA4.High()
}

func OLED_RES_Clr() {
	PA3.Low()
}

func OLED_RES_Set() {
	PA3.High()
}

func OLED_CS_Clr() {
	PA2.Low()
}

func OLED_CS_Set() {
	PA2.High()
}

func OLED_WR_Byte(data, cmd byte) {
	if cmd == OLED_CMD {
		OLED_DC_Set()
	} else {
		OLED_DC_Clr()
	}

	OLED_CS_Clr()

	for i := 0; i < 8; i++ {
		OLED_SCL_Clr()
		if ((data << i) & 0x80) != 0 {
			OLED_SDA_Set()
		} else {
			OLED_SDA_Clr()
		}
		OLED_SCL_Set()

	}
	OLED_CS_Set()
	OLED_DC_Set()
}

func OLED_Init() {

	PA5.Configure(machine.PinConfig{Mode: machine.PinOutput})
	PA7.Configure(machine.PinConfig{Mode: machine.PinOutput})
	PA4.Configure(machine.PinConfig{Mode: machine.PinOutput})
	PA3.Configure(machine.PinConfig{Mode: machine.PinOutput})
	PA2.Configure(machine.PinConfig{Mode: machine.PinOutput})

	OLED_RES_Clr()
	time.Sleep(time.Millisecond * 200)
	OLED_RES_Set()

	OLED_WR_Byte(0xAE, OLED_CMD) /*display off*/
	OLED_WR_Byte(0x02, OLED_CMD) /*set lower column address*/
	OLED_WR_Byte(0x10, OLED_CMD) /*set higher column address*/
	OLED_WR_Byte(0x40, OLED_CMD) /*set display start line*/
	OLED_WR_Byte(0xB0, OLED_CMD) /*set page address*/
	OLED_WR_Byte(0x81, OLED_CMD) /*contract control*/
	OLED_WR_Byte(0xcf, OLED_CMD) /*128*/
	OLED_WR_Byte(0xA1, OLED_CMD) /*set segment remap*/
	OLED_WR_Byte(0xA6, OLED_CMD) /*normal / reverse*/
	OLED_WR_Byte(0xA8, OLED_CMD) /*multiplex ratio*/
	OLED_WR_Byte(0x3F, OLED_CMD) /*duty = 1/64*/
	OLED_WR_Byte(0xad, OLED_CMD) /*set charge pump enable*/
	OLED_WR_Byte(0x8b, OLED_CMD) /* 0x8B �ڹ� VCC */
	OLED_WR_Byte(0x33, OLED_CMD) /*0X30---0X33 set VPP 9V */
	OLED_WR_Byte(0xC8, OLED_CMD) /*Com scan direction*/
	OLED_WR_Byte(0xD3, OLED_CMD) /*set display offset*/
	OLED_WR_Byte(0x00, OLED_CMD) /* 0x20 */
	OLED_WR_Byte(0xD5, OLED_CMD) /*set osc division*/
	OLED_WR_Byte(0x80, OLED_CMD)
	OLED_WR_Byte(0xD9, OLED_CMD) /*set pre-charge period*/
	OLED_WR_Byte(0x1f, OLED_CMD) /*0x22*/
	OLED_WR_Byte(0xDA, OLED_CMD) /*set COM pins*/
	OLED_WR_Byte(0x12, OLED_CMD)
	OLED_WR_Byte(0xdb, OLED_CMD) /*set vcomh*/
	OLED_WR_Byte(0x40, OLED_CMD)

	OLED_WR_Byte(0xAF, OLED_CMD) /*display ON*/
}

func OLED_Refresh() {

	for i := byte(0); i < 8; i++ {

		OLED_WR_Byte(0xb0+i, OLED_CMD)
		OLED_WR_Byte(0x02, OLED_CMD)
		OLED_WR_Byte(0x10, OLED_CMD)
		for n := 0; n < 128; n++ {
			OLED_WR_Byte(OLED_GRAM[n][i], OLED_DATA)
		}
	}
}

func OLED_Clear() {

	for i := 0; i < 8; i++ {

		for n := 0; n < 128; n++ {
			{
				OLED_GRAM[n][i] = 0
			}
		}
	}

}

func OLED_Clear2() {

	for i := 0; i < 8; i++ {

		for n := 0; n < 128; n++ {
			{
				OLED_GRAM[n][i] = 0xFF
			}
		}
	}

}
